import asyncio
import time
from functools import wraps

from loguru import logger


def concurrency(size=1):
    '''
    :param size: 并发数, 默认1
    :param daemon: 是否是守护线程, 默认True
    :return:
    '''

    def deco(function):
        @wraps(function)
        async def function_exec(*args, **kwargs):
            coroutines = []
            assert 'tasks' in kwargs, "param tasks is null!"
            while True:
                if not kwargs['tasks']:
                    break
                for i in range(size):
                    if kwargs['tasks']:
                        kwargs['task'] = kwargs['tasks'].pop()
                        coroutines.append(asyncio.create_task(function(*args, **kwargs)))
                    else:
                        break
                await asyncio.gather(*coroutines)
        return function_exec

    return deco


@concurrency(10)
async def test(task, tasks):
    logger.info(task)
    await asyncio.sleep(3)


if __name__ == "__main__":
    asyncio.run(test(tasks=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]))
    #time.sleep(7)
